package rat;
/*
 *     Copyright 2006 Robert Burrell Donkin
 *  
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

import rat.license.ILicense;
import rat.license.ILicenseMatcher;
import rat.license.standard.UnknownLicense;

/**
 * <p>Reads from a stream to check license.</p>
 * <p><strong>Note</strong> that this class is not thread safe.</p> 
 */
class LicenseCheckWorker {

	public static final String FIRST_LICENSE_LINE = "Licensed under the Apache License, Version 2.0 (the \"License\")";
	public static final String LICENSE_REFERENCE_LINE = "http://www.apache.org/licenses/LICENSE-2.0";
	public static final int DEFAULT_NUMBER_OF_RETAINED_HEADER_LINES = 50;
	
	private final int numberOfRetainedHeaderLines;
	private final String name;
	private final BufferedReader reader;
	private final ILicenseMatcher matcher;
	
	private ILicense license = null;
	
	private int headerLinesToRead;
	private boolean finished = false;
	private Exception error = null;

	public LicenseCheckWorker(String name, Reader reader, int numberOfRetainedHeaderLine, final ILicenseMatcher matcher) {
		this(name, new BufferedReader(reader), numberOfRetainedHeaderLine, matcher);
	}
	
	
	/**
	 * Convenience constructor wraps given <code>Reader</code> 
	 * in a <code>BufferedReader</code>.
	 * @param name the name of the checked content, possibly null
	 * @param reader a <code>Reader</code> for the content, not null
	 */
	public LicenseCheckWorker(String name, Reader reader, final ILicenseMatcher matcher) {
		this(name, new BufferedReader(reader), matcher);
	}
	
	public LicenseCheckWorker(String name, BufferedReader reader, final ILicenseMatcher matcher) {
		this(name, reader, DEFAULT_NUMBER_OF_RETAINED_HEADER_LINES, matcher);
	}
	
	public LicenseCheckWorker(String name, BufferedReader reader, int numberOfRetainedHeaderLine, final ILicenseMatcher matcher) {
		this.name = name;
		this.reader = reader;
		this.numberOfRetainedHeaderLines = numberOfRetainedHeaderLine;
		this.matcher = matcher;
	}	
	
	public boolean isFinished() {
		return finished;
	}


	public Exception getError() {
		return error;
	}

	/**
	 * Gets license for this file.
	 * @return <code>ILicense</code>, not null
	 */
	public ILicense getLicense() {
		return license;
	}
	
	public String getName() {
		return name;
	}

	public boolean isLicenseApproved() {
		boolean result = false;
		final ILicense license = getLicense();
		if (license != null)
		{
			result = license.isAcceptable();
		}
		return result;
	}

	void read() {
		if (!finished) {
			final StringBuffer headers = new StringBuffer();
			headerLinesToRead = numberOfRetainedHeaderLines;
			try {
				while(readLine(headers));
				if (license == null) {
					final String notes = headers.toString();
					license = new UnknownLicense(notes);
				}
			} catch (IOException e) {
				error = e;
			}
			try {
				reader.close();
			} catch (IOException e) {
				// swallow
			}
            matcher.reset();
		}
		finished = true;
	}
	
	boolean readLine(StringBuffer headers) throws IOException {
		String line = reader.readLine();
		boolean result = line != null;
		if (result) {
			if (headerLinesToRead-- > 0) {
				headers.append(line);
				headers.append('\n');
			}
			license = matcher.match(line);
			if (license != null) {
				result = false;
			}
		}
		return result;
	}
}
